package com.dtflys.easyel.runtime.eval;

import com.dtflys.easyel.ast.ASTInvokeExpression;
import com.dtflys.easyel.exception.EasyElEvalException;
import com.dtflys.easyel.exception.EasyElNoSuchMethodException;
import com.dtflys.easyel.runtime.EasyElRuntimeContext;
import com.dtflys.easyel.utils.InvokeUtils;

import java.lang.reflect.InvocationTargetException;

/**
 * @author gongjun[jun.gong@thebeastshop.com]
 * @since v1.0.0
 */
public class InvokeEvaluator {

    public Object evaluate(EasyElRuntimeContext context, ASTInvokeExpression invokeExpression,
                           Object left, Object[] arguments) {
        String methodName = invokeExpression.getMethodName().getText();
        try {
            if (invokeExpression.isStatic()) {
                Class clazz = invokeExpression.getStaticType().getClazz();
                return InvokeUtils.invokeStatic(clazz, methodName, arguments);
            }
            if (left == null) {
                throw new EasyElEvalException(context, invokeExpression.getMethodName(),
                        "Can not resolve method \"" + methodName + "\"");
            }
            return InvokeUtils.invoke(left, methodName, arguments);
        } catch (NoSuchMethodException e) {
            throw new EasyElNoSuchMethodException(context, invokeExpression, e.getMessage());
        } catch (EasyElEvalException e) {
            throw e;
        } catch (InvocationTargetException e) {
            throw new EasyElEvalException(context, invokeExpression, e.getCause().toString());
        } catch (Throwable e) {
            throw new EasyElEvalException(context, invokeExpression, e.getMessage());
        }
    }

}
